package com.lagou.ipersistence.builder;

import com.google.protobuf.Any;
import com.lagou.ipersistence.cache.Cache;
import com.lagou.ipersistence.mapping.*;
import com.lagou.ipersistence.scripting.LanguageDriver;
import com.lagou.ipersistence.session.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Yan Jiahong
 * Created on 2020/11/15
 */
public class MapperBuilderAssistant extends BaseBuilder {
    private String currentNamespace;
    private final String resource;
    private Cache currentCache;
    
    public MapperBuilderAssistant(Configuration configuration, String resource) {
        super(configuration);
        this.resource = resource;
    }
    
    public String getCurrentNamespace() {
        return currentNamespace;
    }
    
    public void setCurrentNamespace(String currentNamespace) {
        this.currentNamespace = currentNamespace;
    }
    
    public String getResource() {
        return resource;
    }
    
    public Cache getCurrentCache() {
        return currentCache;
    }
    
    public void setCurrentCache(Cache currentCache) {
        this.currentCache = currentCache;
    }
    
    public MappedStatement addMappedStatement(
            String id,
            SqlSource sqlSource,
            StatementType statementType,
            SQLCommandType sqlCommandType,
            Class<?> parameterType,
            String resultMap,
            Class<?> resultType,
            LanguageDriver languageDriver) {
        id = applyCurrentNamespace(id);
        boolean isSelect = sqlCommandType == SQLCommandType.SELECT;
        MappedStatement.Builder builder =
                new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType)
                        .resource(resource)
                        .resultMaps(getStatementResultMaps(resultMap, resultType, id));
        MappedStatement statement = builder.build();
        configuration.addMappedStatement(statement);
        
        return statement;
    }
    
    private List<ResultMap> getStatementResultMaps(String resultMap, Class<?> resultType, String statementId) {
        List<ResultMap> resultMaps = new ArrayList<>();
        if (resultType != null) {
            ResultMap inlineResultMap = new ResultMap.Builder(
                    configuration,
                    statementId + "-inline",
                    resultType, new ArrayList<>())
                                                .build();
            resultMaps.add(inlineResultMap);
        }
        return resultMaps;
    }
    
    private String applyCurrentNamespace(String base) {
        if (base == null) {
            return null;
        }
        if (base.startsWith(currentNamespace + ".")) {
            return base;
        }
        if (base.contains(".")) {
            throw new BuilderException("元素名字中不允许包含'.', 请从'" + base + "'中移除");
        }
        return currentNamespace + "." + base;
    }
    
}
